from PIL import Image
import os

def generate_cube_obj(filename="cube.obj"):
    """生成一个标准的立方体 OBJ 文件。"""
    vertices = [
        (1.0, -1.0, -1.0), (1.0, -1.0, 1.0), (-1.0, -1.0, 1.0), (-1.0, -1.0, -1.0),
        (1.0, 1.0, -1.0), (1.0, 1.0, 1.0), (-1.0, 1.0, 1.0), (-1.0, 1.0, -1.0)
    ]
    texcoords = [
        (0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0)
    ]
    normals = [
        (0.0, 0.0, -1.0), (0.0, 0.0, 1.0), (1.0, 0.0, 0.0), (-1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, -1.0, 0.0)
    ]
    faces = [
        ((0, 0, 0), (4, 1, 0), (7, 2, 0), (3, 3, 0)),  # back
        ((1, 0, 1), (5, 1, 1), (6, 2, 1), (2, 3, 1)),  # front
        ((4, 0, 2), (5, 1, 2), (1, 2, 2), (0, 3, 2)),  # right
        ((7, 0, 3), (6, 1, 3), (2, 2, 3), (3, 3, 3)),  # left
        ((4, 0, 4), (7, 1, 4), (3, 2, 4), (0, 3, 4)),  # top
        ((1, 0, 5), (2, 1, 5), (6, 2, 5), (5, 3, 5))   # bottom
    ]

    with open(filename, 'w') as f:
        f.write("# Standard Cube OBJ File generated by gen_grass.py\n")
        f.write("mtllib cube_texture.mtl\n")
        f.write("s off\n")
        for v in vertices:
            f.write(f"v {v[0]} {v[1]} {v[2]}\n")
        for vt in texcoords:
            f.write(f"vt {vt[0]} {vt[1]}\n")
        for vn in normals:
            f.write(f"vn {vn[0]} {vn[1]} {vn[2]}\n")
        f.write("usemtl cube_material\n")
        for face in faces:
            f.write("f")
            for v_index, vt_index, vn_index in face:
                f.write(f" {v_index + 1}/{vt_index + 1}/{vn_index + 1}")
            f.write("\n")
    print(f"Standard cube OBJ file generated: {filename}")

def create_uv_texture(output_filename="cube_texture.png", size=64):
    """创建立方体的 UV 贴图，将六个 16x16 的面合并成一个图片。"""
    face_size = 16
    new_image = Image.new('RGB', (size, size))

    face_names = ["top", "bottom", "left", "right", "front", "back"]
    images = {}
    for name in face_names:
        filepath = f"{name}.png"
        if os.path.exists(filepath):
            try:
                img = Image.open(filepath).convert("RGB")
                if img.size != (face_size, face_size):
                    print(f"Warning: Image '{filepath}' is not 16x16. Resizing...")
                    img = img.resize((face_size, face_size))
                images[name] = img
            except Exception as e:
                print(f"Error loading image '{filepath}': {e}")
                return None
        else:
            print(f"Error: Image '{filepath}' not found.")
            return None

    # UV layout for a standard cube (adjust if your UVs in OBJ are different)
    # Assuming the OBJ UVs are laid out in a common way.
    # This layout might need adjustments based on the exact UV mapping in the generated cube.obj
    uv_map = {
        "right": (face_size * 2, face_size),
        "left": (0, face_size),
        "top": (face_size, 0),
        "bottom": (face_size, face_size * 2),
        "front": (face_size, face_size),
        "back": (face_size * 3, face_size),
    }

    for name, pos in uv_map.items():
        if name in images:
            new_image.paste(images[name], pos)

    try:
        new_image.save(output_filename)
        print(f"UV texture image generated: {output_filename}")
        return output_filename
    except Exception as e:
        print(f"Error saving UV texture: {e}")
        return None

def generate_mtl_file(texture_filename="cube_texture.png", mtl_filename="cube_texture.mtl"):
    """生成一个简单的 MTL 文件引用 UV 纹理。"""
    with open(mtl_filename, 'w') as f:
        f.write("# Material file for the standard cube\n")
        f.write("newmtl cube_material\n")
        f.write("Ka 1.0 1.0 1.0\n")  # Ambient color
        f.write("Kd 1.0 1.0 1.0\n")  # Diffuse color
        f.write("Ks 0.0 0.0 0.0\n")  # Specular color
        f.write("Ns 1.0\n")         # Specular exponent
        f.write(f"map_Kd {texture_filename}\n") # Diffuse texture map
    print(f"Material file generated: {mtl_filename}")

if __name__ == "__main__":
    generate_cube_obj()
    texture_file = create_uv_texture()
    if texture_file:
        generate_mtl_file(texture_file)